home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
program
/
recio215.zip
/
RGETT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-26
|
17KB
|
423 lines
/*****************************************************************************
MODULE: rgett.c
PURPOSE: recio character delimited time input functions
COPYRIGHT: (C) 1994-1996, William Pierpoint
COMPILER: Borland C Version 3.1
OS: MSDOS Version 6.2
VERSION: 2.15
RELEASE: October 26, 1996
*****************************************************************************/
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "recio.h"
extern int _risready(REC *rp, int mode);
extern char *_rfldstr(REC *rp, size_t len);
extern char *_rerrs(REC *rp, int errnum);
#define rtmfmt(rp) ((rp)->r_tmfmt)
int _rgett_c_warno; /* warning number */
int _recbegyr = RECBEGYR; /* year time format %y begins */
/****************************************************************************/
static int /* return number of digits read */
istrncpy( /* copy up to n digits from src to dst */
char *dst, /* destination string */
const char *src, /* source string */
int n) /* number of digits to copy */
/****************************************************************************/
{
int i;
/* copy up to n digits */
for (i=0; i < n; i++) {
if (isdigit(*src)) {
*dst++ = *src++;
} else {
break;
}
}
/* append string terminator */
*dst = '\0';
return i;
}
/****************************************************************************/
void /* returns nothing */
rsetbegyr( /* sets beginning year for time format %y */
int year) /* beginning year */
/****************************************************************************/
{
_recbegyr = year;
}
/****************************************************************************/
void /* returns nothing */
_tminit( /* initialize a tm struct */
struct tm *t) /* tm struct */
/****************************************************************************/
{
t->tm_sec = 0;
t->tm_min = 0;
t->tm_hour = 0;
t->tm_mday = 1;
t->tm_mon = 0;
t->tm_year = 70;
t->tm_isdst = -1;
}
/****************************************************************************/
struct tm /* return tm */
timetotm( /* convert time_t to struct tm */
time_t time) /* source time */
/****************************************************************************/
{
struct tm t;
if (time == (time_t)-1) _tminit(&t);
else memcpy(&t, localtime(&time), sizeof(struct tm));
return t;
}
/****************************************************************************/
time_t /* return time (-1=error) */
tmtotime( /* convert struct tm to time_t */
struct tm t) /* broken-down time source */
/****************************************************************************/
{
time_t time; /* return time (-1 = error) */
/* note: see section 3.5 of design.txt for mktime range */
time = mktime(&t);
if (time == (time_t) -1) errno = ERANGE;
return time;
}
/****************************************************************************/
time_t /* return time (-1=error) */
sftotime( /* convert formated string to time_t */
const char *s, /* source string with time data */
const char *fmt) /* time format */
/****************************************************************************/
{
time_t time=(time_t) -1; /* return time (-1=error) */
struct tm t; /* broken-down time */
t = sftotm(s, fmt);
if (!errno) time = tmtotime(t);
return time;
}
/****************************************************************************/
struct tm /* return tm (if error, errno != 0) */
sftotm( /* convert formated string to tm */
const char *str, /* source string with time data */
const char *fmt) /* time format */
/****************************************************************************/
{
struct tm t; /* tm struct for time */
char buf[5]; /* string buffer */
char *s; /* pointer to string str */
char *q; /* temporary pointer to string s */
s = (char *) str;
errno = 0;
_rgett_c_warno = 0;
_tminit(&t);
for (;;) {
/* skip white space */
while (isspace(*s)) s++;
while (isspace(*fmt)) fmt++;
if (!*s || !*fmt) break;
if (*fmt == '%') {
switch (*++fmt) {
case 'm': /* month (1 to 12) */
q = s;
s += istrncpy(buf, s, 2);
if (*buf) {
fmt++;
while (isspace(*s)) s++;
while (isspace(*fmt)) fmt++;
if (*s=='\0' || isdigit(*s) || *fmt==*s) {
t.tm_mon = atoi(buf) - 1;
if (t.tm_mon < 0 || t.tm_mon > 11) {
/* error - out of domain */
errno = EDOM;
goto done;
}
if (*s != '\0' && !isdigit(*s)) s++;
} else {
_rgett_c_warno = R_WTMFMT;
s = q;
}
if (*fmt != '\0' && *fmt != '%') fmt++;
}
break;
case 'd': /* day of month (1 to 31) */
q = s;
s += istrncpy(buf, s, 2);
if (*buf) {
fmt++;
while (isspace(*s)) s++;
while (isspace(*fmt)) fmt++;
if (*s=='\0' || isdigit(*s) || *fmt==*s) {
t.tm_mday = atoi(buf);
if (t.tm_mday < 1 || t.tm_mday > 31) {
/* error - out of domain */
errno = EDOM;
goto done;
}
if (*s != '\0' && !isdigit(*s)) s++;
} else {
_rgett_c_warno = R_WTMFMT;
s = q;
}
if (*fmt != '\0' && *fmt != '%') fmt++;
}
break;
case 'y': /* 2-digit year */
q = s;
s += istrncpy(buf, s, 2);
if (*buf) {
fmt++;
while (isspace(*s)) s++;
while (isspace(*fmt)) fmt++;
if (*s=='\0' || isdigit(*s) || *fmt==*s) {
t.tm_year = atoi(buf);
if (t.tm_year - (_recbegyr % 100) >= 0) {
t.tm_year += 100 * (_recbegyr / 100) - 1900;
} else {
t.tm_year += 100 * (_recbegyr / 100) - 1800;
}
if (*s != '\0' && !isdigit(*s)) s++;
} else {
_rgett_c_warno = R_WTMFMT;
s = q;
}
if (*fmt != '\0' && *fmt != '%') fmt++;
}
break;
case 'Y': /* 4-digit year */
q = s;
s += istrncpy(buf, s, 4);
if (*buf) {
fmt++;
while (isspace(*s)) s++;
while (isspace(*fmt)) fmt++;
if (*s=='\0' || isdigit(*s) || *fmt==*s) {
t.tm_year = atoi(buf) - 1900;
if (*s != '\0' && !isdigit(*s)) s++;
} else {
_rgett_c_warno = R_WTMFMT;
s = q;
}
if (*fmt != '\0' && *fmt != '%') fmt++;
}
break;
case 'H': /* hour (0 to 23) */
q = s;
s += istrncpy(buf, s, 2);
if (*buf) {
fmt++;
while (isspace(*s)) s++;
while (isspace(*fmt)) fmt++;
if (*s=='\0' || isdigit(*s) || *fmt==*s) {
t.tm_hour = atoi(buf);
if (t.tm_hour > 23) {
/* error - out of domain */
errno = EDOM;
goto done;
}
if (*s != '\0' && !isdigit(*s)) s++;
} else {
_rgett_c_warno = R_WTMFMT;
s = q;
}
if (*fmt != '\0' && *fmt != '%') fmt++;
}
break;
case 'M': /* minute (0 to 59) */
q = s;
s += istrncpy(buf, s, 2);
if (*buf) {
fmt++;
while (isspace(*s)) s++;
while (isspace(*fmt)) fmt++;
if (*s=='\0' || isdigit(*s) || *fmt==*s) {
t.tm_min = atoi(buf);
if (t.tm_min > 59) {
/* error - out of domain */
errno = EDOM;
goto done;
}
if (*s != '\0' && !isdigit(*s)) s++;
} else {
_rgett_c_warno = R_WTMFMT;
s = q;
}
if (*fmt != '\0' && *fmt != '%') fmt++;
}
break;
case 'S': /* second (0 to 61) */
/* includes up to two leap seconds */
q = s;
s += istrncpy(buf, s, 2);
if (*buf) {
fmt++;
while (isspace(*s)) s++;
while (isspace(*fmt)) fmt++;
if (*s=='\0' || isdigit(*s) || *fmt==*s) {
t.tm_sec = atoi(buf);
if (t.tm_sec > 61) {
/* error - out of domain */
errno = EDOM;
goto done;
}
if (*s != '\0' && !isdigit(*s)) s++;
} else {
_rgett_c_warno = R_WTMFMT;
s = q;
}
if (*fmt != '\0' && *fmt != '%') fmt++;
}
break;
case '%': /* literal % */
if (*s=='%') {
s++;
fmt++;
} else {
/* error (invalid literal) */
errno = EINVAL;
goto done;
}
break;
default:
/* error (invalid format specifier) */
errno = EINVAL;
goto done;
}
} else {
if (*s==*fmt) {
s++;
fmt++;
continue;
} else {
/* error (mismatch between data and specifier string) */
errno = ERANGE;
goto done;
}
}
}
done:
if (!errno) {
/* warning if any non-whitespace part of format string left */
while (isspace(*fmt)) fmt++;
if (*fmt) _rgett_c_warno = R_WTMFMT;
} else {
_rgett_c_warno = 0;
}
return t;
}
/****************************************************************************/
struct tm /* return tm */
rgettm( /* get time from record stream */
REC *rp) /* record pointer */
/****************************************************************************/
{
struct tm t; /* return tm */
struct tm val; /* conversion value */
char *fldptr; /* pointer to field buffer */
_tminit(&t);
if (_risready(rp, R_READ)) {
fldptr = _rfldstr(rp, 0);
if (fldptr) {
strims(fldptr);
for (;;) {
if (*fldptr != '\0') {
val = sftotm(fldptr, rtmfmt(rp));
if (errno) {
switch (errno) {
case EINVAL:
fldptr = _rerrs(rp, R_EINVAL);
break;
case EDOM:
fldptr = _rerrs(rp, R_EDOM);
break;
case ERANGE:
fldptr = _rerrs(rp, R_EINVDAT);
break;
default:
fldptr = _rerrs(rp, R_EFAULT);
break;
}
if (fldptr) { continue; } else { goto done; }
} else {
t = val;
if (_rgett_c_warno) rsetwarn(rp, _rgett_c_warno);
goto done;
}
} /* missing data */
fldptr = _rerrs(rp, R_EMISDAT);
if (fldptr) { continue; } else { goto done; }
}
}
}
done:
return t;
}
/****************************************************************************/
struct tm /* return tm */
rngettm( /* get time from field number */
REC *rp, /* record pointer */
unsigned num) /* field number */
/****************************************************************************/
{
rgotofld(rp, num);
return rgettm(rp);
}
/****************************************************************************/
time_t /* return time (-1=error) */
rgett( /* get time from record stream */
REC *rp) /* record pointer */
/****************************************************************************/
{
time_t time=(time_t) -1; /* return time (-1 = error) */
char *fldptr; /* pointer to field buffer */
if (_risready(rp, R_READ)) {
time = tmtotime(rgettm(rp));
while (time == (time_t) -1) {
fldptr = _rerrs(rp, R_ERANGE);
if (fldptr) {
time = tmtotime(sftotm(fldptr, rtmfmt(rp)));
} else {
break;
}
}
}
return time;
}
/****************************************************************************/
time_t /* return time (-1=error) */
rngett( /* get time from field number */
REC *rp, /* record pointer */
unsigned num) /* field number */
/****************************************************************************/
{
rgotofld(rp, num);
return rgett(rp);
}